﻿using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace block_explorer
{
    class ConsoleLog : DrawableGameComponent
    {
        private SpriteBatch mSpriteBatch;
        private SpriteFont mFont;
        private List<ConsoleLine> mLines;
        private Rectangle mRect;
        private int mMaxLines;

        public SpriteFont Font { get { return mFont; } set { mFont = value; } }

        public ConsoleLog(BlockExplorer game)
            : base(game)
        {
            mLines = new List<ConsoleLine>();
            mMaxLines = 20;
        }

        public override void Initialize()
        {
            mSpriteBatch = new SpriteBatch(Game.GraphicsDevice);
            base.Initialize();
        }

        protected override void LoadContent()
        {
            base.LoadContent();

            mFont = Game.Content.Load<SpriteFont>("ConsoleFont");
        }

        public void SetSize(Rectangle rect)
        {
            mRect = rect;
        }

        public void AddLine(string str)
        {
            lock (mLines)
            {
                mLines.Add(new ConsoleLine(str));

                if (mLines.Count > mMaxLines)
                    mLines.RemoveRange(0, 1);
            }
        }

        public override void Draw(GameTime gameTime)
        {
            Viewport oldVp = Game.GraphicsDevice.Viewport;
            Game.GraphicsDevice.Viewport = new Viewport(mRect);

            lock (mLines)
            {
                mSpriteBatch.Begin();
                int y = mRect.Height;
                for (int i = mLines.Count - 1; i >= 0; --i)
                {
                    mLines[i].Draw(mSpriteBatch, mFont, 0, y, mRect.Width);
                    y -= mLines[i].GetLastDrawnHeight();
                }
                mSpriteBatch.End();
            }

            Game.GraphicsDevice.Viewport = oldVp;
            GraphicsDevice.BlendState = BlendState.Opaque;
            GraphicsDevice.DepthStencilState = DepthStencilState.Default;
        }
    }

    class ConsoleLine
    {
        private string[] mWords;
        private List<string> mLines;
        private int mLastHeight;

        public ConsoleLine(string str)
        {
            mWords = str.Split(' ');
            mLines = new List<string>();
        }

        public int GetLastDrawnHeight()
        {
            return mLastHeight;
        }

        public void Draw(SpriteBatch spriteBatch, SpriteFont font, int x, int y, int width)
        {
            string temp = "";
            foreach (string word in mWords)
            {
                if (font.MeasureString(word).X + font.MeasureString(temp).X >= width)
                {
                    mLines.Add(temp);
                    temp = "";
                }
                temp += word + " ";
            }
            if (temp != "")
                mLines.Add(temp);

            Vector2 bounds = font.MeasureString(mLines[0]);
            int lineHeight = (int)bounds.Y;
            mLastHeight = lineHeight * mLines.Count;
            int yPos = y - mLastHeight;
            foreach (string line in mLines)
            {
                spriteBatch.DrawString(font, line, new Vector2(x, yPos), Color.Yellow);
                yPos += lineHeight;
            }

            mLines.Clear();
        }
    }
}
